<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
class Channel extends Model
{
    protected $table = 'channel';
    
    /**
     * 是否主动维护时间戳
     *
     * @var bool
     */
    public $timestamps = false;
    
    public static $TYPES = array(
            0=>array(
                    'title'=>'好顺吧',
            ),
            1=>array(
                    'title'=>'券码无忧',
            ),
            2=>array(
                    'title'=>'充值吧',
            ),
    );
    
    public static function channelPost($channel,$action,$param){
        if (!isset($channel['appid'])) {
            $api = explode(',', $channel['apitoken']);
            $channel['appid'] = $api[0];
            $channel['appkey'] = $api[1];
        }
        if ($channel['type'] == 0) {
            $url = $channel['host']."/API/";
            if ($action == 'submit'){
                $url .= "submit";
                $data = array(
                        'tradeno'=>$param['orderno'],
                        'mobile'=>$param['mobile'],
                        'gid'=>$param['itemno'],
                        'total'=>1,
                );
            }elseif ($action == 'goods'){
                $url .= "good";
                $data = array(
                        'gids'=>isset($param['gids']) ? implode(",", $param['gids']) : '',
                );
            }
            $post = array(
                    'appid'=>$channel['appid'],
                    'timestamp'=>time(),
            );
            if ($data) $post['data'] = json_encode($data);
            $post['sign'] = md5($post['appid'].$post['data'].$post['timestamp'].$channel['appkey']);
            $resp = curPost($url,$post,1);
            $res = json_decode($resp,true);
            if ($action == 'submit'){
                if (isset($res) && $res['code'] == 1){
                    $result = array('code'=>1,'transid'=>$res['ordersn']);
                    if (isset($res['content']) && $res['content']) $result['content'] = $res['content'];
                }else{
                    $result = array('code'=>0,'msg'=>$res['msg']);
                    if ($res['code'] == 2) $result['nocredit'] = 1;
                }
            }elseif ($action == 'goods') $result = array('code'=>1,'list'=>$res['list'] ?? []);
        }elseif ($channel['type'] == 1){
            $url = $channel['host']."/api/";
            $time = time()."000";
            $header = array("Content-type:application/json;charset=utf-8","channelid:OP0002","txntime:".$time,"devCode:".$channel['appid']);
            $token = Redis::get("channel_mahua_token".$channel['appid']);
            if (!$token) {
                $nheader = $header;
                $nheader[] = "sign:".md5("{}".$channel['appkey'].$time);
                $res = curPost($url."user-server/user/dev/login","{}",1,$nheader);
                $res = json_decode($res,true);
                Redis::setex("channel_mahua_token".$channel['appid'],3600,$res['rtnData']['token']);
                $token = $res['rtnData']['token'];
            }
            $header[] = "token:".$token;
            if ($action == 'submit') {
                $shost = $channel['sitehost']??$_SERVER['HTTP_HOST'];
                if (empty($shost)) return array('code'=>0,'msg'=>'sitehost为空');
                if ($channel['gtype'] == 0) {
                    $post = array(
                            'id'=>$param['itemno'],
                            'buyNum'=>1,
                            'autoCommitHours'=>$param['extra'],
                            'outId'=>$param['orderno'],
                    );
                }else{
                    $post = array(
                            'productId'=>$param['itemno'],
                            'accounts'=>[$param['mobile']],
                            'outId'=>$param['orderno'],
                            'callBackUrl'=>"https://{$shost}/channelnotify/{$channel['uniacid']}/{$channel['type']}/order",
                    );
                    if (isset($param['extra'])) $post['minutes'] = $param['extra'] * 60;
                }
                $post = json_encode($post);
                $header[] = "sign:".md5($post.$channel['appkey'].$time);
                if ($channel['gtype'] == 0) $url .= "coupons-server/coupons/info/out/pay/applyAndPay";
                else $url .= "coupons-server/coupons/vediocharge/put/add";
                $res = curPost($url,$post,1,$header);
                $res = json_decode($res,true);
                if ($res['rtnCode'] == '000000'){
                    $res = $res['rtnData'][0];
                    $result = array('code'=>1,'transid'=>$res['id']);
                    if ($channel['gtype'] == 0) {
                        if (isset($res['infoQrcodeImgid']) && $res['infoQrcodeImgid']) $result['content'] = $res['infoQrcodeImgid'];
                        elseif (isset($res['infoCardno']) && $res['infoCardno']) $result['content'] = $res['infoCardno'];
                        elseif (isset($res['infoCardpwd']) && $res['infoCardpwd']) $result['content'] = $res['infoCardpwd'];
                        elseif (isset($res['infoMsg']) && $res['infoMsg']) $result['content'] = $res['infoMsg'];
                    }
                }else{
                    $result = array('code'=>0,'msg'=>$res['rtnMsg']);
                    if ($res['rtnCode'] == '010407') $result['nocredit'] = 1;
                }
            }elseif ($action == 'goods') {
                $list = [];
                foreach ($param['gids'] as $gid) {
                    $ngid = explode("_", $gid);
                    $post = json_encode(array('id'=>$ngid[0]));
                    $nheader = $header;
                    $nheader[] = "sign:".md5($post.$channel['appkey'].$time);
                    if($channel['gtype'] == 0) $nurl = $url."coupons-server/coupons/info/dev/out/info/detail";
                    elseif (!isset($ngid[1])) $nurl = $url."coupons-server/coupons/vediocharge/info/put/fast/productdetail";
                    else $nurl = $url."coupons-server/coupons/vediocharge/info/put/slow/productdetail";
                    $result = curPost($nurl,$post,1,$nheader);
                    $res = json_decode($result,true);
                    if (!isset($res['rtnCode']) || $res['rtnCode'] != '000000'){
                        continue;
                    }
                    if($channel['gtype'] == 0) $res['rtnData'] = $res['rtnData'][0];
                    if (isset($res['rtnData']['status']) && $res['rtnData']['status']){
                        if($channel['gtype'] == 0){
                            foreach ($res['rtnData']['prices'] as $v) {
                                if ($v['hours'] == $ngid[1]) {
                                    $list[] = array('id'=>$res['rtnData']['id'],'price'=>$v['outBPrice'],'title'=>$res['rtnData']['couponName'].($res['rtnData']['couponSuffixName']??''));
                                    break;
                                }
                            }
                        }elseif (!isset($ngid[1])) $list[] = array('id'=>$res['rtnData']['id'],'price'=>$res['rtnData']['putAmount'],'title'=>$res['rtnData']['couponName'].$res['rtnData']['couponNameType'].($res['rtnData']['couponSuffixName']??''));
                        else{
                            foreach ($res['rtnData']['putAmountList'] as $v) {
                                if ($v['mintues'] == $ngid[1] * 60) {
                                    $list[] = array('id'=>$res['rtnData']['id'],'price'=>$v['putAmount'],'title'=>$res['rtnData']['couponName'].$res['rtnData']['couponNameType'].($res['rtnData']['couponSuffixName']??''));
                                    break;
                                }
                            }
                        }
                    }
                }
                return array('code'=>1,'list'=>$list);
            }
//         }elseif ($channel['type'] == 3){
//             $url = $channel['host']."/dcapi/";
//             $post = array();
//             if ($channel['gtype'] == 0) {
//                 if ($action == 'submit') {
//                     $url .= "card/payOrder";
//                     $post = array(
//                             'appid'=>$channel['appid'],
//                             'out_order_id'=>$param['orderno'],
//                             'card_id'=>$param['itemno'],
//                             'auto_confirm_hour'=>$param['extra'],
//                             'num'=>1,
//                             'order_money'=>'0'
//                     );
//                     ksort($post);
//                     $post['sign'] = strtoupper(md5(ToUrlParams($post)."&appsecret=".$channel['appkey']));
//                     $res = curPost($url, $post,1);
//                     $res = json_decode($res,1);
//                     if ($res && $res['code'] == 1){
//                         $res = $res['result'][0];
//                         $r = [];
//                         if (isset($res['card_num']) && $res['card_num']) $r[] = $res['card_num'];
//                         if (isset($res['card_pass']) && $res['card_pass']) $r[] = $res['card_pass'];
//                         $result = array('code'=>1,'transid'=>$res['order_id'],'content'=>implode("|", $r));
//                     }else $result = array('code'=>0,'msg'=>$res['msg']);
//                 }elseif ($action == 'goods') {
//                     $url .= "card/queryCardDetail";
//                     $post = array(
//                             'appid'=>$channel['appid'],
//                     );
//                     $list = [];
//                     foreach ($param['gids'] as $gid) {
//                         $ngid = explode("_", $gid);
//                         $post['id'] = $ngid[0];
//                         ksort($post);
//                         $post['sign'] = strtoupper(md5(ToUrlParams($post)."&appsecret=".$channel['appkey']));
//                         $res = curPost($url, $post,1);
//                         $res = json_decode($res,1);
//                         if ($res && $res['code'] == 1){
//                             $d = $res['result'];
//                             if ($d && $d['num'] > 0){
//                                 foreach ($d['priceList'] as $v) {
//                                     if ($v['hours'] == $ngid[1]) {
//                                         $list[] = array('id'=>$post['id'],'price'=>$v['price'],'title'=>$d['card_name'].$d['name']);
//                                         break;
//                                     }
//                                 }
//                             }
//                         }
//                     }
//                     $result = array('code'=>1,'list'=>$list);
//                 }
//             }else{
//                 if ($action == 'submit') {
//                     $shost = $channel['sitehost']??$_SERVER['HTTP_HOST'];
//                     if (empty($shost)) return array('code'=>0,'msg'=>'sitehost为空');
//                     $url .= "pay";
//                     $post = array(
//                             'appid'=>$channel['appid'],
//                             'out_order_id'=>$param['orderno'],
//                             'account'=>$param['mobile'],
//                             'card_id'=>$param['itemno'],
//                             'number'=>1,
//                             'datetime'=>time(),
//                             'notify_url'=>"https://{$shost}/channelnotify/{$channel['uniacid']}/{$channel['type']}/order"
//                     );
//                     ksort($post);
//                     $data = $post;
//                     $data['notify_url'] = urlencode($data['notify_url']);
//                     $data['account'] = urlencode($data['account']);
//                     $post['sign'] = strtoupper(md5(ToUrlParams($data)."&appsecret=".$channel['appkey']));
//                     $res = curPost($url, $post,1);
//                     $res = json_decode($res,1);
//                     if ($res && $res['code'] == 1) $result = array('code'=>1,'transid'=>$res['result']);
//                     else $result = array('code'=>0,'msg'=>$res['msg']);
//                 }elseif ($action == 'goods') {
//                     $url .= "queryCardInfo";
//                     $post = array(
//                             'appid'=>$channel['appid'],
//                     );
//                     $list = [];
//                     foreach ($param['gids'] as $gid) {
//                         $post['id'] = $gid;
//                         ksort($post);
//                         $post['sign'] = strtoupper(md5(ToUrlParams($post)."&appsecret=".$channel['appkey']));
//                         $res = curPost($url, $post,1);
//                         $res = json_decode($res,1);
//                         if ($res && $res['code'] == 1){
//                             $d = $res['result'];
//                             if ($d && $d['demand_num'] > 0) $list[] = array('id'=>$gid,'price'=>$d['price'],'title'=>$d['card_name'].$d['name']);
//                         }
//                     }
//                     $result = array('code'=>1,'list'=>$list);
//                 }
//             }
        }elseif ($channel['type'] == 2){
            $url = $channel['host']."/api/";
            $token = Redis::get("channel_czb_token".$channel['appid']);
            if (!$token) {
                $result = curPost($url,array('action'=>'login','mobile'=>$channel['appid'],'passwd'=>$channel['appkey']),1);
                $res = json_decode($result,true);
                if ($res['code'] == 0) return $res;
                $token = $res['token'];
                Redis::setex("channel_czb_token".$channel['appid'],3600,$res['token']);
            }
            $post = ['action'=>$action];
            if ($action == 'goods'){
                $post['action'] = 'price';
                $post['gids'] = isset($param['gids']) ? implode(",", $param['gids']) : '';
            }elseif ($action == 'submit'){
                $post = array(
                        'tradeno'=>$param['orderno'],
                        'param'=>$param['mobile'],
                        'gid'=>$param['itemno'],
                        'total'=>1,
                        'action'=>'create'
                );
                if (isset($param['extra'])) $post['extdata'] = $param['extra'];
            }else $post = array_merge($post,$param);
            $post['token'] = $token;
            $result = curPost($url,$post,1);
            $res = json_decode($result,true);
            if ($action == 'submit') {
                if (isset($res) && $res['code'] == 1){
                    $result = array('code'=>1,'transid'=>$res['ordersn']);
                    if (isset($res['content']) && $res['content']) $result['content'] = $res['content'];
                }else{
                    $result = array('code'=>0,'msg'=>$res['msg']);
                    if ($res['code'] == 2) $result['nocredit'] = 1;
                }
            }elseif ($action == 'goods') $result = array('code'=>1,'list'=>$res['list'] ?? []);
            else $result = $res;
        }
        if ($action == 'submit'){
            try {
                Log::build(['driver' => 'single','path' => storage_path('logs/channel/'.date('Ymd'))])->info("url: ".$url);
                Log::build(['driver' => 'single','path' => storage_path('logs/channel/'.date('Ymd'))])->info("post: ".json_encode($post));
                Log::build(['driver' => 'single','path' => storage_path('logs/channel/'.date('Ymd'))])->info("result: ".json_encode($result));
            } catch (\Exception $e) {
            }
        }
        return $result;
    }
    
    public static function notify($req,$ctype,$ntype){
        if ($ntype == 'order') {
            Log::build(['driver' => 'single','path' => storage_path('logs/channel/notify'.date('Ymd'))])->info($ctype == 1 ? $req->getContent() : json_encode($req->post()));
            if ($ctype == 0) {
                $data = $req->post();
                $json = htmlspecialchars_decode($data['data']);
                $data = json_decode($json,true);
                if(!isset($data['tradeno']) || empty($data['tradeno'])) return;
                Channel::orderDone($data);
            }elseif ($ctype == 1){
                $data = json_decode($req->getContent(),true);
                if (isset($data['putMode']) && $data['putMode'] == 0 && $data['putStatus'] == 2) $data['putStatus'] = 4;
                if(isset($data['outId']) && $data['outId'] && in_array($data['putStatus'], [3,4])){
                    $data['tradeno'] = $data['outId'];
                    $data['status'] = $data['putStatus'] == 4 ? 2 : 3;
                    Channel::orderDone($data);
                }
                return '{"rtnCode": "000000","rtnMsg": "成功!"}';
            }elseif ($ctype == 2){
                $data = $req->post();
                if(!isset($data['out_order_id']) || empty($data['out_order_id'])) return 'success';
                if(in_array($data['status'], [3,6])){
                    $data['tradeno'] = $data['out_order_id'];
                    $data['status'] = $data['status'] == 3 ? 2 : 3;
                    Channel::orderDone($data);
                }
                return 'success';
            }elseif ($ctype == 3){
                $data = $req->post();
                if(!isset($data['tradeno']) || empty($data['tradeno'])) return;
                Channel::orderDone($data);
            }
        }elseif ($ntype == 'good'){
            if ($ctype == 1){
                Log::build(['driver' => 'single','path' => storage_path('logs/channel/notify'.date('Ymd'))])->info($req->getContent());
                $data = json_decode($req->getContent(),true);
                $channel = Channel::where('type',1)->get();
                foreach ($channel as $v) {
                    $goods = FeeItem::where('cid',$v->id)->where('itemno',$data['configId'])->get()->toArray();
                    if (empty($goods)) $goods = GoodItem::where('cid',$v->id)->where('itemno',$data['configId'])->get()->toArray();
                    if (empty($goods)) continue;
                    if ($data['tag'] == 'put_status') {
                        foreach ($goods as $g) {
                            if ($data['status'] && $g->status == 1 || !$data['status'] && $g->status == 0) {
                                $g->status = $data['status'] ? 0 : 1;
                                $g->save();
                            }
                        }
                    }elseif ($data['tag'] == 'put_amount'){
                        foreach ($goods as $g) {
                            $g->costprice = $data['nAmount'];
                            $g->save();
                        }
                    }
                }
                return '{"rtnCode": "000000","rtnMsg": "成功!"}';
            }
        }
    }
    
    public static function updateGoods(){
        $list1 = FeeItem::select('id','cid','itemno','status')->get();
        $list2 = GoodItem::select('id','cid','itemno','status')->get();
        $goods = [];
        foreach ($list1 as $value) {
            if (!isset($goods[$value['cid']])) $goods[$value['cid']] = [];
            $goods[$value['cid']][] = $value;
        }
        foreach ($list2 as $value) {
            if (!isset($goods[$value['cid']])) $goods[$value['cid']] = [];
            $value['id'] = $value['id'].'G';
            $goods[$value['cid']][] = $value;
        }
        if (empty($goods)) return;
        foreach ($goods as $cid => $list) {
                $c = Channel::find($cid);
                if (!$c && $c->type == 1) continue;
                $itemnos = $ggs = [];
                foreach ($list as $v) {
                    if (!isset($v['itemno']) || empty($v['itemno'])) continue;
                    $itemnos[] = $v['itemno'];
                    $ggs[$v['itemno']] = $v;
                }
                if (empty($itemnos)) continue;
                $res = Channel::channelPost($c, 'goods', array('gids'=>array_unique($itemnos)));
                if (isset($res['list'])) {
                    $gids = [];
                    foreach ($res['list'] as $v) {
                        $gids[$v['id']] = $v;
                    }
                    foreach ($itemnos as $gid) {
                        $g = $ggs[$gid];
                        if (isset($gids[$gid])) {
                            $u = array('costprice'=>$gids[$gid]['price'],'status'=>0);
                        }else $u = array('status'=>1);
                        if (strpos($g['id'], 'G') > 0) GoodItem::where('id',str_replace("G",'',$g['id']))->update($u);
                        else FeeItem::where('id',$g['id'])->update($u);
                    }
                }
        }
    }
    
    public static function orderDone($data){
        $ordersn = explode("_", $data['tradeno']);
        $order = Order::where('ordersn',$ordersn[0])->first();
        if (empty($order) || $order->status != 1) return;
        if ($data['status'] == 2) Order::orderSucc($order);
        else Order::orderFail($order,$data['reason']??'');
    }
}
